<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        //发布订阅模式, 又称"观察者模式"
        //概念: 发布者
        //概念: 订阅者
        //关系: 发布者和订阅者是 一对多的关系

        (function(){
            function Observer(){
                
                this.obj = {};
                // this.obj = {
                //     'lijiaqi': [ function(){},function(){}, ... ],
                //     'weiya': [ function(){},function(){}, ... ],
                // }

                //订阅消息
                //参数一: 消息类型 , 是string类型
                //参数二: 用来接收消息的函数 , 是function类型
                this.on = function(type,handler){ //订阅消息
                    //保存该消息类型及用来接收消息的函数
                    // this.obj[type] = (this.obj[type]?this.obj[type]:[])
                    this.obj[type] = this.obj[type] || [];
                    this.obj[type].push( handler ); 
                }

                //发布消息
                this.emit = function(type,msg){ //发布消息
                    //拿到type对应这个类型消息的所有订阅者的回调函数, 调用该函数并将消息传给订阅者

                    // if( this.obj[type] ){ //做个判断,防止this.obj[type]获取不到而报错.
                    //     this.obj[type].forEach((item)=>{
                    //         item(msg);
                    //     })
                    // }

                    // 上面的if判断可以简化为 && 与表达式
                    this.obj[type] &&
                    this.obj[type].forEach((item)=>{ //遍历并调用每个回调函数
                        item(msg);
                    })
                }

            }

            window.Observer = Observer;//暴露函数到外面
        })()

        //实例化对象
        var os = new Observer();

        //订阅消息
        os.on('lijiaqi',function(msg){
            //这里接收来自发布者的消息 msg
            console.log('李莉 收到了来自lijiaqi的消息: ' + msg);
        })

        //订阅消息
        os.on('lijiaqi',function(msg){
            //这里接收来自发布者的消息 msg
            console.log('李丽 收到了来自lijiaqi的消息: ' + msg);
        })

        //订阅消息
        os.on('lijiaqi',function(msg){
            //这里接收来自发布者的消息 msg
            console.log('莉莉 收到了来自lijiaqi的消息: ' + msg);
        })

        //订阅消息
        os.on('weiya',function(msg){
            //这里接收来自发布者的消息 msg
            console.log('李丽 收到了来自lijiaqi的消息: ' + msg);
        })
        //订阅消息
        os.on('weiya',function(msg){
            //这里接收来自发布者的消息 msg
            console.log('莉莉 收到了来自lijiaqi的消息: ' + msg);
        })

        //订阅消息
        // os.on('liyang',function(msg){
        //     //这里接收来自发布者的消息 msg
        //     console.log('李阳的小米地 收到了来自liyang的消息: ' + msg);
        // })

        console.log(os);

        //发布消息
        os.emit('lijiaqi','本周六补课!')
        // os.emit('weiya','本周六买买买!')
        // os.emit('liyang','本周六疯狂英语周!')

    </script>
</body>
</html>